package com.carlinfo.userscenter.users.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.carlinfo.common.service.BaseService;
import com.carlinfo.common.util.PageInfoUtil;
import com.carlinfo.userscenter.users.dao.IAMenuDao;
import com.carlinfo.userscenter.users.dao.IARoleMenuDao;
import com.carlinfo.userscenter.users.dao.impl.AMenuDaoImpl;
import com.carlinfo.userscenter.users.dao.impl.ARoleMenuDaoImpl;
import com.carlinfo.userscenter.users.pojo.AMenu;
import com.carlinfo.userscenter.users.pojo.ARole;
import com.carlinfo.userscenter.users.pojo.ARoleMenu;
import com.carlinfo.userscenter.users.pojo.ARoleMenuEnum;
import com.carlinfo.userscenter.users.service.IAuthService;
import com.carlinfo.userscenter.users.service.IUserService;

/**
 * 权限相关的Service类
 * @author wangshMac
 *
 */
public class AuthServiceImpl extends BaseService implements IAuthService
{
	/**
	 * =左边是父类
	 * =右边是子类
	 * 父类引用指向子类对象
	 */
	private IAMenuDao menuDao = new AMenuDaoImpl();
	private IARoleMenuDao roleMenuDao = new ARoleMenuDaoImpl() ;
	
	/* 创建一个Service 
	 * 会出现相互引用的问题
	 * 使用读写器赋值
	 * 得new对象,然后才能调用读写器
	 * */
	private IUserService usersService;
	
	/**
	 * {
			// 响应码/
			"code":"0",
			//响应码的描述 
			"info":"成功",
			"data":
			{
				//id:
				"id":"",
				//sql语句影响的条数
				"effect":""
			}
		}
	 */
	@Override
	public JSONObject saveOneMenuService(AMenu menu)
	{
		JSONObject resultJSON = new JSONObject() ; 
		/* dao返回值指的是执行sql语句影响力的条数 */
		int res =  this.menuDao.saveOneDao(menu);
		if(res > 0 )
		{
			/* 添加成功 */
			JSONObject dataJSON = new JSONObject() ; 
			/* 在json中,id是整数 */
			dataJSON.put("id", menu.getId() + "");
			/* ""+任何类型,结果都是字符串类型 */
			dataJSON.put("effect", res + "");
			/* 将resultJSON和dataJSON关联起来 */
			resultJSON.put("data", dataJSON);
			
			resultJSON.put("code", "0");
			resultJSON.put("info", "添加成功");
		}else
		{
			/* 添加失败 */
			resultJSON.put("code", "1");
			resultJSON.put("info", "添加失败");
		}
		return resultJSON ; 
	}

	@Override
	public JSONObject updateOneMenuService(AMenu menu)
	{
		JSONObject resultJSON = new JSONObject() ; 
		/* dao返回值指的是执行sql语句影响力的条数 */
		int res =  this.menuDao.updateOneDao(menu);
		if(res > 0 )
		{
			/* 添加成功 */
			JSONObject dataJSON = new JSONObject() ; 
			/* ""+任何类型,结果都是字符串类型 */
			dataJSON.put("effect", res + "");
			/* 将resultJSON和dataJSON关联起来 */
			resultJSON.put("data", dataJSON);
			
			resultJSON.put("code", "0");
			resultJSON.put("info", "更新成功");
		}else
		{
			/* 添加失败 */
			resultJSON.put("code", "1");
			resultJSON.put("info", "更新失败");
		}
		return resultJSON ; 
	}

	@Override
	public JSONObject deleteOneMenuService(AMenu menu)
	{
		JSONObject resultJSON = new JSONObject() ; 
		/* dao返回值指的是执行sql语句影响力的条数 */
		int res =  this.menuDao.deleteOneDao(null);
		if(res > 0 )
		{
			/* 添加成功 */
			JSONObject dataJSON = new JSONObject() ; 
			/* ""+任何类型,结果都是字符串类型 */
			dataJSON.put("effect", res + "");
			/* 将resultJSON和dataJSON关联起来 */
			resultJSON.put("data", dataJSON);
			
			resultJSON.put("code", "0");
			resultJSON.put("info", "删除成功");
		}else
		{
			/* 添加失败 */
			resultJSON.put("code", "1");
			resultJSON.put("info", "删除失败");
		}
		return resultJSON ; 
	}

	@Override
	public AMenu findOneMenuService(Map<String, Object> condMap)
	{
		AMenu menu = this.menuDao.selectOneDao(condMap);
		if("true".equalsIgnoreCase(condMap.get("extend") + ""))
		{
			Map<String, Object> extMap = new HashMap<String, Object>();
			/* 如何查询关联关系呢?
			 * 如何查询父菜单和子菜单呢?
			 *  */
			/* 查询父菜单
			 * 如:查询id为2的菜单;这里面有一个parentid(上一级菜单的id);
			 * 拿着id=parentId;查询的就是id为2的父菜单
			 *  */
			extMap.put("id", menu.getParentId());
			AMenu parentMenu = this.findOneMenuService(extMap);
			menu.setParentMenu(parentMenu);
			/* 如何查询当前菜单的所有子菜单;当前菜单有多个子菜单
			 * parnetid = id;就是所有的子菜单
			 *  */
			/*
			 * 查询子菜单,不能分页;
			 * parentId = 当前菜单的id
			 * */
			extMap.clear();
			extMap.put("parentId", menu.getId()) ; 
			List<AMenu> childMenuList = this.findCondListMenuService(null, extMap);
			menu.setChildMenuList(childMenuList);
			
			/* 为角色菜单赋值 
			 * 查询指定菜单下面的角色菜单
			 * */
			extMap.clear();
			extMap.put("menuId", menu.getId()) ; 
			/* 1 表示启用 */
			extMap.put("status", ARoleMenuEnum.STATUS_ENABLE.getStatus());
			List<ARoleMenu> childRoleMenuList = this.findCondListRoleMenuService(null, extMap);
			menu.setChildRoleMenuList(childRoleMenuList);
		}
		return menu ;
	}

	@Override
	public List<AMenu> findCondListMenuService(PageInfoUtil pageInfoUtil ,Map<String, Object> condMap)
	{
		List<AMenu> menuList = this.menuDao.selectListDao(pageInfoUtil,condMap);
		if("true".equalsIgnoreCase(condMap.get("extend") + ""))
		{
			Map<String, Object> extMap = new HashMap<String, Object>();
			for (Iterator<AMenu> iterator = menuList.iterator(); iterator.hasNext();)
			{
				AMenu menu = (AMenu) iterator.next();
				
				/* 如何查询关联关系呢?
				 * 如何查询父菜单和子菜单呢?
				 *  */
				/* 查询父菜单
				 * 如:查询id为2的菜单;这里面有一个parentid(上一级菜单的id);
				 * 拿着id=parentId;查询的就是id为2的父菜单
				 *  */
				extMap.put("id", menu.getParentId());
				AMenu parentMenu = this.findOneMenuService(extMap);
				menu.setParentMenu(parentMenu);
				/* 如何查询当前菜单的所有子菜单;当前菜单有多个子菜单
				 * parnetid = id;就是所有的子菜单
				 *  */
				/*
				 * 查询子菜单,不能分页;
				 * parentId = 当前菜单的id
				 * */
				extMap.clear();
				extMap.put("parentId", menu.getId()) ; 
				List<AMenu> childMenuList = this.findCondListMenuService(null, extMap);
				menu.setChildMenuList(childMenuList);
			}
		}
		return menuList ; 
	}

	@Override
	public List<AMenu> findChildTreeMenuService(AMenu menu)
	{
		List<AMenu> resultList = new ArrayList<AMenu>();
		List<AMenu> paramsMenuList = new ArrayList<AMenu>();
		if(menu == null)
		{
			/* 查询所有的一级节点
			 * 所有parentId为0的都是一级节点
			 *  */
			Map<String, Object> extMap = new HashMap<String, Object>();
			extMap.put("parentId", "0");
			/* 木有查询关联关系 */
			/*extMap.put("extend", "true");*/
			paramsMenuList = this.findCondListMenuService(null, extMap);
		}else
		{
			/* 只查询当前节点
			 * 参数的节点,到底有木有为子节点集合赋值呢?我们不能要求方法的调用者
			 *  */
			paramsMenuList.add(menu);
		}
		
		/* paramsMenuList:即将查询树形结构的节点 */
		for (Iterator iterator = paramsMenuList.iterator(); iterator.hasNext();)
		{
			AMenu menuTemp = (AMenu) iterator.next();
			/* 查询当前节点的树形结构 */
			this.findChildTreeMenuServiceUtil(menuTemp , 0,resultList);
		}
		return resultList;
	}
	
	/**
	 * 递归:自己调用自己
	 * 递归保留结果:有两种形式
	 * 		~将结果放到返回值中保留
	 * 		~将结果放到参数中保留:(强烈使用此种)
	 * |-->
	 * |-->|-->
	 * @param menu
	 * @param resultList 就是为了方法递归存储结果时使用的
	 */
	public void findChildTreeMenuServiceUtil(AMenu menu, int level,List<AMenu> resultList)
	{
		/* 增加的前置字符串 */
		String preStr = "" ; 
		for(int i = 0 ; i < level ; i ++)
		{
			preStr = preStr + "|-->" ; 
		}
		/* 打印的时候是在方法内部打印 */
		//System.out.println(preStr + menu.getName());
		/* 不能这样写,要保留数据库里面的原生字符串 */
		//menu.setName(preStr + menu.getName());
		menu.setTreeName(preStr + menu.getName());
		resultList.add(menu);
		Map<String, Object> extMap = new HashMap<String, Object>();
		/* 重新现查询子节点 */
		/*List<AMenu> childMenuList = menu.getChildMenuList() ;*/
		extMap.put("parentId", menu.getId());
		List<AMenu> childMenuList = this.findCondListMenuService(null, extMap);
		for (Iterator<AMenu> iterator = childMenuList.iterator(); iterator.hasNext();)
		{
			AMenu menuChild = (AMenu) iterator.next();
			/* 递归:自己调用自己
			 * 是否会千万死循环呢?
			 * 子节点集合万一是空的呢?就无法调用自己了
			 *  */
			this.findChildTreeMenuServiceUtil(menuChild , level + 1,resultList);
		}
	}

	/**
	 *  [
			{
				id : 1,
				pId : 0,
				name : "一级分类",
				open : true,
				"checked":true
			}
		]
	 */
	@Override
	public JSONArray findChildTreeMenuJSONService(String roleId)
	{
		/* 整棵树 */
		List<AMenu> menuAllTreeList = this.findChildTreeMenuService(null);
		
		Map<String, Object> condMap = new HashMap<String, Object>();
		
		/* 最外面是一个中括号 */
		JSONArray resultArr = new JSONArray() ; 
		for (Iterator iterator = menuAllTreeList.iterator(); iterator.hasNext();)
		{
			AMenu menuTemp = (AMenu) iterator.next();
			
			/* 中括号里面套的是大括号 */
			JSONObject menuJSON = new JSONObject() ; 
			menuJSON.put("id", menuTemp.getId());
			menuJSON.put("pId", menuTemp.getParentId());
			menuJSON.put("name", menuTemp.getName());
			menuJSON.put("open", true);
			if(roleId != null && !"".equalsIgnoreCase(roleId))
			{
				/* 当前的角色和菜单是否有权限
				 * 有木有权限就是查询角色菜单表
				 * 根据角色id和菜单id查询角色菜单表
				 *  */
				condMap.clear();
				condMap.put("roleId", roleId);
				condMap.put("menuId", menuTemp.getId());
				PageInfoUtil pageInfoUtil = new PageInfoUtil() ; 
				/* 创建一个分页对象,木有设置每页多少条和当前页;因为都有默认值 */
				this.findCondListRoleMenuService(pageInfoUtil, condMap);
				if(pageInfoUtil.getTotalRecord() > 0 )
				{
					menuJSON.put("checked", true);
				}
			}
			/* 将当前的节点放到结果中(数组) */
			resultArr.add(menuJSON);
		}
		return resultArr;
	}
	
	/**
	 * {
			// 响应码/
			"code":"0",
			//响应码的描述 
			"info":"成功",
			"data":
			{
				//id:
				"id":"",
				//sql语句影响的条数
				"effect":""
			}
		}
	 */
	@Override
	public JSONObject saveOneRoleMenuService(ARoleMenu roleMenu)
	{
		JSONObject resultJSON = new JSONObject() ; 
		/* dao返回值指的是执行sql语句影响力的条数 */
		int res =  this.roleMenuDao.saveOneDao(roleMenu);
		if(res > 0 )
		{
			/* 添加成功 */
			JSONObject dataJSON = new JSONObject() ; 
			/* 在json中,id是整数 */
			dataJSON.put("id", roleMenu.getId() + "");
			/* ""+任何类型,结果都是字符串类型 */
			dataJSON.put("effect", res + "");
			/* 将resultJSON和dataJSON关联起来 */
			resultJSON.put("data", dataJSON);
			
			resultJSON.put("code", "0");
			resultJSON.put("info", "添加成功");
		}else
		{
			/* 添加失败 */
			resultJSON.put("code", "1");
			resultJSON.put("info", "添加失败");
		}
		return resultJSON ; 
	}

	@Override
	public JSONObject updateOneRoleMenuService(ARoleMenu roleMenu)
	{
		JSONObject resultJSON = new JSONObject() ; 
		/* dao返回值指的是执行sql语句影响力的条数 */
		int res =  this.roleMenuDao.updateOneDao(roleMenu);
		if(res > 0 )
		{
			/* 添加成功 */
			JSONObject dataJSON = new JSONObject() ; 
			/* ""+任何类型,结果都是字符串类型 */
			dataJSON.put("effect", res + "");
			/* 将resultJSON和dataJSON关联起来 */
			resultJSON.put("data", dataJSON);
			
			resultJSON.put("code", "0");
			resultJSON.put("info", "更新成功");
		}else
		{
			/* 添加失败 */
			resultJSON.put("code", "1");
			resultJSON.put("info", "更新失败");
		}
		return resultJSON ; 
	}

	@Override
	public JSONObject deleteOneRoleMenuService(ARoleMenu roleMenu)
	{
		JSONObject resultJSON = new JSONObject() ; 
		/* dao返回值指的是执行sql语句影响力的条数 */
		int res =  this.roleMenuDao.deleteOneDao(null);
		if(res > 0 )
		{
			/* 添加成功 */
			JSONObject dataJSON = new JSONObject() ; 
			/* ""+任何类型,结果都是字符串类型 */
			dataJSON.put("effect", res + "");
			/* 将resultJSON和dataJSON关联起来 */
			resultJSON.put("data", dataJSON);
			
			resultJSON.put("code", "0");
			resultJSON.put("info", "删除成功");
		}else
		{
			/* 添加失败 */
			resultJSON.put("code", "1");
			resultJSON.put("info", "删除失败");
		}
		return resultJSON ; 
	}

	@Override
	public ARoleMenu findOneRoleMenuService(Map<String, Object> condMap)
	{
		ARoleMenu roleMenu =  this.roleMenuDao.selectOneDao(condMap);
		/* 关联关系开关 */
		if("true".equalsIgnoreCase(condMap.get("extend") + ""))
		{
			Map<String, Object> extMap = new HashMap<String, Object>();
			/* 查询角色 */
			extMap.clear();
			extMap.put("id", roleMenu.getRoleId());
			/* 在UsersService中 */
			ARole role = this.usersService.findOneRoleService(extMap);
			roleMenu.setRole(role);
			/* 查询菜单 */
			extMap.clear();
			extMap.put("id", roleMenu.getMenuId());
			AMenu menu = this.findOneMenuService(extMap);
			roleMenu.setMenu(menu);
		}
		return roleMenu ; 
	}

	@Override
	public List<ARoleMenu> findCondListRoleMenuService(PageInfoUtil pageInfoUtil ,Map<String, Object> condMap)
	{
		List<ARoleMenu> roleMenuList = this.roleMenuDao.selectListDao(pageInfoUtil,condMap);
		/* 关联关系开关 */
		if("true".equalsIgnoreCase(condMap.get("extend") + ""))
		{
			Map<String, Object> extMap = new HashMap<String, Object>();
			for (Iterator iterator = roleMenuList.iterator(); iterator.hasNext();)
			{
				ARoleMenu roleMenu = (ARoleMenu) iterator.next();
				
				/* 查询角色 */
				extMap.clear();
				extMap.put("id", roleMenu.getRoleId());
				/* 在UsersService中 */
				ARole role = this.usersService.findOneRoleService(extMap);
				roleMenu.setRole(role);
				/* 查询菜单 */
				extMap.clear();
				extMap.put("id", roleMenu.getMenuId());
				AMenu menu = this.findOneMenuService(extMap);
				roleMenu.setMenu(menu);
			}
		}
		return roleMenuList;
	}

	public void setUsersService(IUserService usersService)
	{
		this.usersService = usersService;
	}
}
